﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Reflection;
using System.Windows.Forms;

namespace UnitTestsScenarioEditor
{
    [TestClass]
    public class UnitTestTerrain
    {
        private Panel panel;
        private Form form;
        private Engine.Engine engine;
        private Tools.Terrain terrain3x3;
        private Tools.Terrain terrain4x4;
        private Engine.Graphics.MaterialManager materialManager;
        private Engine.Graphics.ShaderManager shaderManager;
        private Engine.Camera.Camera camera;

        [TestMethod]
        public void TestGetSectorCoordinate()
        {
            string propertyName = "SECTORSIZE";
            FieldInfo fieldInfo = typeof(Tools.Terrain).GetField(propertyName, BindingFlags.NonPublic | BindingFlags.Static);
            float sectorSize = (float)fieldInfo.GetValue(null);
            float offset = 1.0f;

            // Terrain 3x3

            // South West
            PrivateObject objTerrain3x3 = new PrivateObject(terrain3x3);
            // Die unterste linke Ecke.
            var retVal = objTerrain3x3.Invoke("GetSectorCoordinate", new object[] { new SharpDX.Vector3(-sectorSize * 3.0f / 2.0f, 0, -sectorSize * 3.0f / 2.0f) });
            Assert.AreEqual(retVal, new System.Drawing.Point(0, 0));
            retVal = objTerrain3x3.Invoke("GetSectorCoordinate", new object[] { new SharpDX.Vector3(-sectorSize * 2.0f / 2.0f - offset, 0, -sectorSize * 2.0f / 2.0f - offset) });
            Assert.AreEqual(retVal, new System.Drawing.Point(0, 0));
            // Die obere linke Ecke.
            retVal = objTerrain3x3.Invoke("GetSectorCoordinate", new object[] { new SharpDX.Vector3(-sectorSize * 3.0f / 2.0f, 0, sectorSize * 3.0f / 2.0f - offset) });
            Assert.AreEqual(retVal, new System.Drawing.Point(0, 2));
            // Die unterste rechte Ecke.
            retVal = objTerrain3x3.Invoke("GetSectorCoordinate", new object[] { new SharpDX.Vector3(sectorSize * 3.0f / 2.0f - offset, 0, -sectorSize * 3.0f / 2.0f) });
            Assert.AreEqual(retVal, new System.Drawing.Point(2, 0));
            // Die obere rechte Ecke.
            retVal = objTerrain3x3.Invoke("GetSectorCoordinate", new object[] { new SharpDX.Vector3(sectorSize * 3.0f / 2.0f - offset, 0, sectorSize * 3.0f / 2.0f - offset) });
            Assert.AreEqual(retVal, new System.Drawing.Point(2, 2));
            // das westliche feld
            retVal = objTerrain3x3.Invoke("GetSectorCoordinate", new object[] { new SharpDX.Vector3(-sectorSize * 2.0f / 2.0f + offset, 0, 0) });
            Assert.AreEqual(retVal, new System.Drawing.Point(0, 1));
            retVal = objTerrain3x3.Invoke("GetSectorCoordinate", new object[] { new SharpDX.Vector3(-sectorSize * 2.0f / 2.0f + offset, 0, sectorSize / 2.0f - offset) });
            Assert.AreEqual(retVal, new System.Drawing.Point(0, 1));
            retVal = objTerrain3x3.Invoke("GetSectorCoordinate", new object[] { new SharpDX.Vector3(-sectorSize * 2.0f / 2.0f + offset, 0, -sectorSize / 2.0f) });
            Assert.AreEqual(retVal, new System.Drawing.Point(0, 1));
            // Ausserhalb obere linke Ecke.
            retVal = objTerrain3x3.Invoke("GetSectorCoordinate", new object[] { new SharpDX.Vector3(-sectorSize * 3.0f / 2.0f, 0, sectorSize * 3.0f / 2.0f) });
            Assert.AreEqual(retVal, new System.Drawing.Point(0, 3));
            // Mitte
            retVal = objTerrain3x3.Invoke("GetSectorCoordinate", new object[] { new SharpDX.Vector3(-offset, 0, -offset) });
            Assert.AreEqual(retVal, new System.Drawing.Point(1, 1));
            retVal = objTerrain3x3.Invoke("GetSectorCoordinate", new object[] { new SharpDX.Vector3(offset, 0, -offset) });
            Assert.AreEqual(retVal, new System.Drawing.Point(1, 1));
            retVal = objTerrain3x3.Invoke("GetSectorCoordinate", new object[] { new SharpDX.Vector3(-offset, 0, offset) });
            Assert.AreEqual(retVal, new System.Drawing.Point(1, 1));
            retVal = objTerrain3x3.Invoke("GetSectorCoordinate", new object[] { new SharpDX.Vector3(offset, 0, offset) });
            Assert.AreEqual(retVal, new System.Drawing.Point(1, 1));
        }

        [TestInitialize()]
        public void Initialize()
        {
            try
            {
                this.form = new Form();
                this.panel = new Panel();
                this.form.Controls.Add(this.panel);
                this.engine = new Engine.Engine(panel, this.form.Handle);
                this.materialManager = new Engine.Graphics.MaterialManager(this.engine, ".\\texture\\");
                this.materialManager.AddNewMaterial(new Engine.Graphics.Material("sample", "sample", "sample", Engine.Graphics.EnumMappingMode.material00), false);
                this.shaderManager = new Engine.Graphics.ShaderManager(this.materialManager, ".\\shaders\\", this.engine.Grafic.Device);
                terrain3x3 = new Tools.Terrain(3, 3, 10, 0, this.engine, this.materialManager, this.shaderManager, this.camera, 100000);
                terrain3x3.Camera = this.engine.Camera;
                terrain4x4 = new Tools.Terrain(3, 3, 10, 0, this.engine, this.materialManager, this.shaderManager, this.camera, 100000);
                terrain4x4.Camera = this.engine.Camera;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Assert.Fail();
            }
        }

        [TestCleanup()]
        public void Cleanup()
        {
            if (this.engine != null) this.engine.Dispose();
            if (this.materialManager != null) this.materialManager.Dispose();
            if (this.shaderManager != null) this.shaderManager.Dispose();
        }
    }
}